package cn.thoughtworks.school.programCenter.controllers;

import cn.thoughtworks.school.programCenter.annotations.Auth;
import cn.thoughtworks.school.programCenter.entities.User;
import cn.thoughtworks.school.programCenter.entities.UserRole;
import cn.thoughtworks.school.programCenter.entities.commands.CreateUserOrganization;
import cn.thoughtworks.school.programCenter.entities.commands.CreateUserRoleCommand;
import cn.thoughtworks.school.programCenter.exceptions.BusinessException;
import cn.thoughtworks.school.programCenter.services.ProgramService;
import cn.thoughtworks.school.programCenter.services.UserCenterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping(value = "/api")
public class UserController {
    private final static String SEARCH_STUDENT_PROGRAMS = "student";

    @Autowired
    private ProgramService programService;
    @Autowired
    private UserCenterService userCenterService;

    @GetMapping("/users/{userId}")
    public ResponseEntity getUserById(@PathVariable Long userId) {
        return userCenterService.getUserInfo(userId);
    }

    @GetMapping("/v2/users")
    public ResponseEntity getUsersByUsername(@RequestParam(value = "userName", defaultValue = "") String userName) {
        Map user = userCenterService.getUserByName(userName);

        return ResponseEntity.ok(user);
    }
    @RequestMapping(value = "/v3/users", method = RequestMethod.GET)
    public ResponseEntity searchUsers (@RequestParam(value = "userName") String userName) {
        List<Map> users = userCenterService.getUsersByUsername(userName).getBody();

        return ResponseEntity.ok(users);
    }

    @PostMapping(value = "/users/searches")
    public ResponseEntity searchUsersByCondition(@RequestBody Map condition) {
        List usernameOrEmails = (List) condition.get("usernameOrEmail");
        String userType = condition.get("type").toString();
        List<Map> searchUsers = userCenterService.getUsersByUsernameOrEmail(usernameOrEmails);

        if (Objects.equals(userType, SEARCH_STUDENT_PROGRAMS)) {
            List list = programService.searchStudentsPrograms(searchUsers);
            return new ResponseEntity(list, HttpStatus.OK);
        }

        return new ResponseEntity(programService.searchTutorsPrograms(searchUsers), HttpStatus.OK);
    }

    @PostMapping("organizations/{organizationId}/users/roles")
    public ResponseEntity getUserRolesByCondition(@PathVariable Long organizationId, @RequestBody Map condition) {
        List<UserRole> userRoles = userCenterService.getUserRolesByCondition(organizationId, condition);

        return ResponseEntity.ok(userRoles);
    }

    @PutMapping("users/{userId}/roles")
    public ResponseEntity updateUserRole(@RequestBody CreateUserRoleCommand createUserRoleCommand) {
        userCenterService.updateUserRole(createUserRoleCommand);

        return ResponseEntity.noContent().build();
    }

    @PutMapping(value = "/users/{userId}/organizations")
    public ResponseEntity updateUserCurrentOrganizationId(
        @PathVariable Long userId,
        @RequestBody CreateUserOrganization createUserOrganization) {

        userCenterService.updateUserCurrentOrganizationId(userId, createUserOrganization);

        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @PostMapping("users/import")
    public ResponseEntity importUsers(@RequestParam("file") MultipartFile file,
                                    @Auth User current) throws BusinessException, IOException {
        if (validateYmlZipFormat(file)) {
            userCenterService.importUsers(file, current);
            return new ResponseEntity(HttpStatus.CREATED);
        }
        throw new BusinessException("Wrong format");
    }

    private boolean validateYmlZipFormat(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        return fileName.endsWith(".xls") || fileName.endsWith(".xlsx");
    }
}
